package com.hl.card.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hl.card.common.persistence.model.Recharge;
import com.hl.card.common.remote.resolve.RemoteService;
import com.hl.card.common.remote.user.RemoteUser;
import com.hl.card.common.util.ResponseModel;
import com.hl.card.modular.pack.service.RechargeService;
import com.hl.card.modular.system.service.ISysDicService;
import com.hl.card.pay.dto.RechargeDto;
import com.hl.card.pay.service.PayRechargeService;
import com.hl.card.pay.util.PayDigestUtil;
import com.hl.card.pay.vo.RechargeVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class PayRechargeServiceImpl implements PayRechargeService {
    private Logger logger= LoggerFactory.getLogger(PayRechargeServiceImpl.class);
    @Value("${pay.config.cardUrl}")
    private String cardUrl;

    @Value("${pay.config.mchInfo}")
    private String mchInfo;

    @Value("${pay.config.payChanel}")
    private String payChanel;

    @Value("${pay.config.reqKey}")
    private String reqKey;

    @Value("${pay.config.trade}")
    private String trade;

    @Value("${pay.config.doTrans}")
    private String doTrans;

    @Value("${pay.config.mchId}")
    private String mchId;

    @Value("${pay.redis.recharge.cancelTime}")
    private String cancelTime;

    @Autowired
    private RechargeService rechargeService;
    @Autowired
    private ISysDicService sysDicService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private RemoteService remoteService;

    /**
     * 完成充值
     * @param vo
     * @return
     */
    @Override
    public String doRecharge(RechargeVo vo) {
        ResponseModel responseModel=  findRecharge(vo.getUserId(),vo.getCurrency());
        Object re = responseModel.getData();
        String jsonString=JSONObject.toJSONString(re);
        Recharge recharge=JSON.parseObject(jsonString,Recharge.class);
        RemoteUser remoteUser = remoteService.findUserById(recharge.getUser_id());
        recharge.setStatus(1);
        recharge.setRemarkInfo(vo.getRemarkInfo());
        recharge.setRemarks("充值订单");
        recharge.setConfirm_transfer_time(new Date());
        //TODO  确定用户中心的数据可以取到
        if(null!=remoteUser){
            recharge.setBinding_phone(remoteUser.getMobilePhone());
            recharge.setFull_name(remoteUser.getUserName());
        }
        recharge.insert();
        redisTemplate.delete("recharge"+recharge.getUser_id()+recharge.getCurrency());
        //todo 返回值简化
        JSONObject jobj=new JSONObject();
        jobj.put("resCode","SUCCESS");
        jobj.put("retCode","SUCCESS");
        jobj.put("isSuccess",true);
        return jobj.toJSONString();
    }
    @Override
    public ResponseModel findRecharge(String userId) {
        ResponseModel model=new ResponseModel();
        String orderHtl=redisTemplate.opsForValue().get("recharge"+userId+"htl");
        String orderEth=redisTemplate.opsForValue().get("recharge"+userId+"eth");
        model.setStatus("0001");
        if(orderHtl!=null||orderEth!=null){
            JSONArray array=new JSONArray();
            array.add(JSONObject.parseObject(orderHtl));
            array.add(JSONObject.parseObject(orderEth));
            model.setStatus("0000");
            model.setData(array);
        }
        return model;
    }
    @Override
    public String saveToRedis(Recharge recharge) {
        String jsonStr=JSONObject.toJSONString(recharge);
        redisTemplate.opsForValue().set("recharge"+recharge.getUser_id()+recharge.getCurrency(),jsonStr,Long.parseLong(cancelTime), TimeUnit.MINUTES);
        return jsonStr;
    }
    @Override
    public String findRemark() {
        Map<String, Object> item = sysDicService.selectListByCodeNo("TZCZPZ", "ZZDZ");
        String value = (String) item.get("dicValue");
        return value;
    }

    public Recharge getRedisRecharge(String userId){
        String   rechageStr=  redisTemplate.opsForValue().get("rechange"+userId);
        return JSONObject.parseObject(rechageStr,Recharge.class);
    }
    @Override
    public List<Recharge> findRechargeList(String userId) {
        Recharge recharge=new Recharge();
        recharge.setUser_id(userId);
        recharge.setStatus(4);
        return rechargeService.selectMultiCondition(recharge).getRecords();
    }
    @Override
    public ResponseModel findRecharge(String userId, String currency) {
        ResponseModel model=new ResponseModel();
        String order=redisTemplate.opsForValue().get("recharge"+userId+currency);
        model.setStatus("0001");
        if(order!=null){
            model.setStatus("0000");
            model.setData(JSONObject.parseObject(order));
        }
        return model;
    }
    @Override
    public Recharge findRechargeByNo(String userId, String recharge_no) {
        Recharge recharge=new Recharge();
        String orderHtl=redisTemplate.opsForValue().get("recharge"+userId+"htl");
        String orderEth=redisTemplate.opsForValue().get("recharge"+userId+"eth");
        JSONObject objHtl=JSONObject.parseObject(orderHtl);
        JSONObject objEth=JSONObject.parseObject(orderEth);
        return recharge;
    }

    /**
     * 执行最后的转账
     * @param mchTransNo
     * @return
     */
    @Override
    public String doTrans(String mchTransNo,String modifyAmount) {
        System.out.println("转账：doTrans：modifyAmount = " + modifyAmount);
        String url = cardUrl+trade;
        JSONObject paramMap = new  JSONObject();
        paramMap.put("mchTransNo", mchTransNo);
        paramMap.put("mchId",mchId);
        Recharge rechage = rechargeService.selectById(mchTransNo);
        if(!StringUtils.isEmpty(modifyAmount)){
            rechage.setActual_amount(Double.parseDouble(modifyAmount));
        }
        rechage.updateById();
        //todo 更新一下 rechage
        RechargeDto rechargeDto=new RechargeDto();
        rechargeDto.setChannelUser(rechage.getUser_id());
        rechargeDto.setMchTransNo(mchTransNo);
        rechargeDto.setAction("RECHARGE");
        rechargeDto.setRemarkInfo("数字币充值");
        //todo 这里要考虑一下 是进行4舍5入 还是去掉小数点后面的
        String amount=rechage.getAmount().intValue()+"";
        rechargeDto.setAmount(modifyAmount);
        rechargeDto.setParam1("0");
        rechargeDto.setSubject("CZ");
        rechargeDto.setBody("数字币充值");
        rechargeDto.setClientIp("211.94.116.218");
        rechargeDto.setCurrency(rechage.getCurrency());
        rechargeDto.setMchId(mchId);
        paramMap= (JSONObject) JSON.toJSON(rechargeDto);
        //商户信息
        //商户的reqkey
        String reqSign = PayDigestUtil.getSign(paramMap, reqKey);
        paramMap.put("sign", reqSign);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        System.out.println(paramMap.toJSONString());
        map.add("params",paramMap.toJSONString());
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        String str = restTemplate.postForEntity(url, request, String.class).getBody();
        return str;
    }
    @Override
    public void cancel(String userId, String currency) {
        redisTemplate.delete("recharge"+userId+currency);
    }
    /**
     * 从redis里搜索 所有的 充值订单
     * @return
     */
    @Override
    public List<Recharge> getRedisRechargeList() {
        return null;
    }

    @Override
    public String getRedis(String key) {
        String recharge=redisTemplate.opsForValue().get(key);
        return recharge;
    }

    @Override
    public boolean checkRecharge(String userId, double amount) {
        return true;
    }


    @Override
    public String rechargeTokenWallet(String userId, String currency, String amount,String remarkInfo,String hash) {
        String str="";
        try{
        Double modifyAmount = Double.parseDouble(amount);
        String url = cardUrl + trade;
        JSONObject paramMap = new JSONObject();
        paramMap.put("mchTransNo", hash);
        paramMap.put("mchId", mchId);
        Recharge exitCharge = rechargeService.selectById(hash);
        if (exitCharge != null && exitCharge.getStatus() == 4) {
            return "已经充过了";
        }
        RechargeDto rechargeDto = new RechargeDto();
        rechargeDto.setChannelUser(userId);
        rechargeDto.setMchTransNo(hash);
        rechargeDto.setAction("RECHARGE");
        rechargeDto.setRemarkInfo(remarkInfo);
        rechargeDto.setAmount(amount);
        rechargeDto.setParam1("0");
        rechargeDto.setSubject("CZ");
        rechargeDto.setBody("数字币充值");
        rechargeDto.setClientIp("211.94.116.218");
        rechargeDto.setCurrency(currency);
        rechargeDto.setMchId(mchId);
        paramMap = (JSONObject) JSON.toJSON(rechargeDto);
        //商户的reqkey
        String reqSign = PayDigestUtil.getSign(paramMap, reqKey);
        paramMap.put("sign", reqSign);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        System.out.println(paramMap.toJSONString());
        map.add("params", paramMap.toJSONString());
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        str = restTemplate.postForEntity(url, request, String.class).getBody();
        JSONObject object = JSONObject.parseObject(str);
        //未保存失败订单到本地
        if(!object.get("retCode").equals("SUCCESS")){
            return str;
        }
        Recharge recharge = new Recharge();
        RemoteUser remoteUser = remoteService.findUserById(recharge.getUser_id());
        recharge.setStatus(4);
        recharge.setRemarkInfo("");
        recharge.setRemarks("钱包充值订单");
        recharge.setAdd_time(new Date());
        if (null != remoteUser) {
            recharge.setBinding_phone(remoteUser.getMobilePhone());
            recharge.setFull_name(remoteUser.getUserName());
        }
        recharge.setExtra("RECHARGE");
        recharge.setCurrency(currency);
        recharge.setAmount(modifyAmount);
        recharge.setActual_amount(modifyAmount);
        recharge.setUser_id(userId);
        recharge.setRecharge_no(hash);
        recharge.setRemarkInfo(remarkInfo);
        recharge.insert();
    }catch(Exception ex){
        ex.printStackTrace();
        System.out.println("---充值报错--");
    }
        return str;
    }

}
